<template>
  <view
    class="mdl-avatar__wrap"
    :class="[width ? '' : 'mdl-avatar__size-' + size, radius === -1 ? 'mdl-avatar__' + shape : '']"
    :style="wrapStyles"
    @tap="handleClick"
  >
    <image
      class="mdl-avatar__img"
      :style="styles"
      :class="[
        radius === -1 ? 'mdl-avatar__' + shape : '',
        width ? '' : 'mdl-avatar__size-' + size,
      ]"
      :src="showImg"
      :mode="mode"
      v-if="src"
      :webp="webp"
      :lazy-load="lazyLoad"
      @error="handleError"
    ></image>
    <text
      class="mdl-avatar__text"
      :class="[width ? '' : 'mdl-avatar__text-' + size]"
      v-if="!src && text"
      :style="textStyles"
      >{{ text }}
    </text>
    <slot></slot>
  </view>
</template>

<script setup>
import { ref, computed, watch } from 'vue'

const props = defineProps({
  src: {
    type: String,
    default: '',
  },
  errorSrc: {
    type: String,
    default: '',
  },
  mode: {
    type: String,
    default: 'widthFix',
  },
  //微信小程序、百度小程序、字节跳动小程序
  //图片懒加载。只针对page与scroll-view下的image有效
  lazyLoad: {
    type: Boolean,
    default: true,
  },
  //默认不解析 webP 格式，只支持网络资源 微信小程序2.9.0
  webp: {
    type: Boolean,
    default: false,
  },
  background: {
    type: String,
    default: '#D1D1D1',
  },
  //small（64）、middle（96）、large（128）
  size: {
    type: String,
    default: 'middle',
  },
  //图片宽度，设置大于0的数值生效，默认使用size
  width: {
    type: [Number, String],
    default: 0,
  },
  //默认等宽，设置图大于0的数值且设置了图片宽度生效
  height: {
    type: [Number, String],
    default: 0,
  },
  //指定头像的形状，可选值为 circle、square
  shape: {
    type: String,
    default: 'circle',
  },
  //图片圆角值，默认使用shape，当设置大于等于0的数值，shape失效
  radius: {
    type: [Number, String],
    default: -1,
  },
  //没有src时可以使用文本代替
  text: {
    type: String,
    default: '',
  },
  color: {
    type: String,
    default: '#fff',
  },
  //默认使用size下字体大小
  fontSize: {
    type: [Number, String],
    default: 0,
  },
  fontWeight: {
    type: [Number, String],
    default: 600,
  },
  marginRight: {
    type: [Number, String],
    default: 0,
  },
  marginBottom: {
    type: [Number, String],
    default: 0,
  },
  //在列表中的索引值
  index: {
    type: Number,
    default: 0,
  },
  //其他参数
  params: {
    type: [Number, String],
    default: 0,
  },
})

const emit = defineEmits(['click', 'error'])

const showImg = ref(props.src || '')

const wrapStyles = computed(() => {
  return `background:${props.background};margin-right:${props.marginRight}rpx;margin-bottom:${props.marginBottom}rpx;${styles.value}`
})

const styles = computed(() => {
  let styles = ''
  if (props.width) {
    styles = `width:${props.width}rpx;height:${props.height || props.width}rpx;`
  }
  if (props.radius !== -1) {
    styles += `border-radius:${props.radius}rpx;`
  }
  return styles
})

const textStyles = computed(() => {
  let styles = `color:${props.color};font-weight:${props.fontWeight};`
  if (props.fontSize) {
    styles += `font-size:${props.fontSize}rpx;`
  }
  return styles
})

watch(() => props.src, (val) => {
  if (val) {
    showImg.value = val
  }
})

const handleError = (e) => {
  if (props.src) {
    if (props.errorSrc) {
      showImg.value = props.errorSrc
    }
    emit('error', {
      index: props.index,
      params: props.params,
    })
  }
}

const handleClick = () => {
  emit('click', {
    index: props.index,
    params: props.params,
  })
}
</script>

<style scoped>
.mdl-avatar__wrap {
  position: relative;
  /* #ifndef APP-NVUE */
  display: inline-flex;
  overflow: hidden;
  flex-shrink: 0;
  z-index: 3;
  /* #endif */
  flex-direction: row;
  align-items: center;
  justify-content: center;
}

.mdl-avatar__img {
  flex: 1;
  /* #ifndef APP-NVUE */
  display: block;
  object-fit: cover;
  /* #endif */
}

.mdl-avatar__text {
  flex: 1;
  /* #ifndef APP-NVUE */
  display: block;
  white-space: nowrap;
  box-sizing: border-box;
  /* #endif */
  /* #ifdef APP-NVUE */
  lines: 1;
  /* #endif */
  overflow: hidden;
  text-overflow: ellipsis;
  text-align: center;
}

.mdl-avatar__size-small {
  width: 64rpx !important;
  height: 64rpx !important;
}

.mdl-avatar__text-small {
  font-size: 32rpx !important;
}

.mdl-avatar__size-middle {
  width: 96rpx !important;
  height: 96rpx !important;
}

.mdl-avatar__text-middle {
  font-size: 44rpx !important;
}

.mdl-avatar__size-large {
  width: 128rpx !important;
  height: 128rpx !important;
}

.mdl-avatar__text-large {
  font-size: 56rpx !important;
}

.mdl-avatar__circle {
  /* #ifdef APP-NVUE */
  border-radius: 500px !important;
  /* #endif */

  /* #ifndef APP-NVUE */
  border-radius: 50% !important;
  /* #endif */
}

.mdl-avatar__square {
  border-radius: 8rpx !important;
}
</style>
